package com.banmao.youZone.job;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson2.JSON;
import com.banmao.youZone.api.ApiService;
import com.banmao.youZone.consts.CommonConst;
import com.banmao.youZone.entity.TaskTrigger;
import com.banmao.youZone.entity.UserVO;
import com.banmao.youZone.mapper.UserMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.Trigger;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.TimeZone;

@Slf4j
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DailyJob extends QuartzJobBean {

    @Resource
    private UserMapper userMapper;

    @Resource
    @Qualifier("jobThreadPool")
    private ThreadPoolTaskExecutor jobThreadPool;

    @Resource
    private ApiService apiService;

    @Override
    protected void executeInternal(JobExecutionContext context) {
        DateTime currentTime = DateUtil.date();
        JobDataMap jobDataMap = context.getMergedJobDataMap();
        int userId = jobDataMap.getInt(CommonConst.USER_ID);
        log.info("[JOB日常任务]执行开始:{},userId:{}", currentTime, userId);

        UserVO userVO = userMapper.selectById(userId);

        if (!userVO.getExecuteJob()) {
            log.info("[JOB日常任务]userId:{}未开启定时打卡", userId);
            return;
        }

        Trigger trigger = context.getTrigger();

        JobDataMap triggerDataMap = trigger.getJobDataMap();
        Object taskJson = triggerDataMap.get(CommonConst.TASK_JSON);
        if (!(taskJson instanceof String)) {
            log.error("[JOB日常任务]异常触发，没有携带任务信息");
            return;
        }

        TaskTrigger taskTrigger = JSON.parseObject((String) taskJson, TaskTrigger.class);

        boolean executeFlag = false;
        Integer mode = taskTrigger.getMode();
        if (mode == 1) {
            if (apiService.judgeNeedExecute(currentTime)) {
                executeFlag = true;
            }
        } else {
            if (!DateUtil.isWeekend(currentTime)) {
                executeFlag = true;
            }
        }
        if (!executeFlag) {
            log.info("[JOB日常任务]userId:{},userName:{}--当前任务不在可执行时间,taskTrigger:{}",
                    userId, userVO.getUsername(), taskJson);
            return;
        }

        log.info("[JOB日常任务]执行taskTrigger:{}", taskJson);

        String timeSectionEnd = taskTrigger.getTimeSectionEnd();

        currentTime = DateUtil.date();
        long lastMillis = countLastMillis(currentTime, timeSectionEnd);
        long sleep = RandomUtil.randomLong(500, Math.max(501, lastMillis - 1500));

        DateTime executeTime = DateUtil.date(currentTime.getTime() + Math.max(sleep, 10));
        taskTrigger.setPredictExecuteTime(executeTime);

        if ("alert".equalsIgnoreCase(taskTrigger.getTaskType())) {
            // 提醒任务
            ExecuteAlertJob.addTask(taskTrigger);
        } else {
            ExecuteClockJob.addTask(taskTrigger);
        }


    }

    private static long countLastMillis(DateTime currentTime, String endHourMinute) {
        String[] split = endHourMinute.split(":");
        Calendar calendar = currentTime.toCalendar();

        calendar.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(split[0]));
        calendar.set(Calendar.MINUTE, Integer.parseInt(split[1]));
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        DateTime endTime = DateUtil.date(calendar);

//        log.info("current:{},entTime:{}", currentTime, endTime);
        long between = DateUtil.between(currentTime, endTime, DateUnit.MS);

        return between;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            DateTime current = DateUtil.date();
            long lastMillis = countLastMillis(current, "15:30");

            long sleep = RandomUtil.randomLong(500, Math.max(501, lastMillis - 1500));

            DateTime executeTime = DateUtil.date(current.getTime() + Math.max(sleep, 10));
            System.out.println("==============> " + executeTime);
        }
    }

}
